package cn.faifai.framework.config;

import com.fasterxml.jackson.databind.ObjectMapper;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import org.springframework.http.converter.json.MappingJackson2HttpMessageConverter;
import org.springframework.web.cors.CorsConfiguration;
import org.springframework.web.cors.UrlBasedCorsConfigurationSource;
import org.springframework.web.filter.CorsFilter;
import org.springframework.web.servlet.config.annotation.CorsRegistry;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;

import java.util.List;

@Configuration
@Slf4j
public class ResourceConfig implements WebMvcConfigurer {

    /**
     * 什么是跨域,为什么由后端处理跨域 ?
     * 在前后端分离的项目中，跨域资源共享（CORS, Cross-Origin Resource Sharing）是一个常见的问题。
     * 这主要是因为浏览器出于安全考虑，实施了同源策略（Same-Origin Policy），即默认情况下，浏览器会阻
     * 止从一个源（origin）加载的文档或脚本试图与另一个源的资源进行交互。这里的“源”是由协议、域名和端口三者共同决定的。
     * 在前后端分离的项目中，前端通常部署在一个服务器上（例如，通过Nginx、Apache等部署在HTTP服务器上），
     * 而后端则部署在另一个服务器上（可能是Tomcat、Node.js、Spring Boot等应用服务器）。由于前后端部署在不同的源上，
     * 当前端尝试通过AJAX请求与后端进行交互时，就会遇到跨域问题，浏览器会阻止这些跨域请求。
     *
     * CORS（跨域资源共享，Cross-Origin Resource Sharing）是一种基于HTTP头的机制，用于控制不同源
     * （源指协议、域名和端口三者）之间的资源共享。在Web开发中，CORS机制允许Web服务器通过跨源HTTP请求头部
     * 来告诉浏览器，哪些跨源请求是被允许的，从而允许Web应用程序安全地进行跨源数据传输。
     *
     * 为了解决跨域问题，CORS机制允许服务器显式地指定哪些外部网站可以访问其资源。这通过服务器在响应头中增加一些特定的HTTP头部来实现。
     * 当浏览器接收到这些头部信息时，会判断当前请求是否符合CORS策略，从而决定是否允许跨域请求。
     *
     * 由后端处理跨域可以由可控的服务器来指定允许跨域的源, 安全性高
     */
    @Override
    public void addCorsMappings(CorsRegistry registry) {
        registry.addMapping("/**")
                .allowedOrigins("http://localhost:5173") // 允许访问的源
                .allowedMethods("GET", "POST", "PUT", "DELETE") // 允许的HTTP方法
                .allowedHeaders("*") // 允许的头信息
                .allowCredentials(true) // 是否允许发送Cookie
                .maxAge(3600); // 预检请求的缓存时间（秒）
    }
}
